﻿using System;
using System.IO;
using Core.Interfaces;
using Core.IocHelpers;

namespace Core.Settings
{
  ///<summary>
  ///  Settings
  ///</summary>
  ///<remarks>
  ///  Stored in App settings in registry?
  ///</remarks>
  [AutoRegister]
  public class CurrentEnvironment : IEnvironment
  {
    private readonly ICommunityImporter _communityImporter;
    private ICommunity _community;
    private FileSystemWatcher _fileSystemWatcher;

    ///<summary>
    ///</summary>
    ///<param name="communityImporter"></param>
    public CurrentEnvironment(ICommunityImporter communityImporter)
    {
      _communityImporter = communityImporter;
      Settings = IoC.Container.Resolve<IAppSettings>();
      Settings.FilePathChanged += (sender, args) => SetupFileWatcher();

      SetupFileWatcher();
    }

    #region IEnvironment Members

    public IAppSettings Settings { get; private set; }

    public ICommunity Community
    {
      get
      {
        if (_community == null)
        {
          _communityImporter.ImportCommunity(Settings.SourceXmlCommunityFilePath);

          if (_communityImporter.Successful)
          {
            _community = _communityImporter.Community;
          }
          else
          {
            throw new InvalidDataException(_communityImporter.ErrorMessages.JoinedAsString());
          }
        }

        return _community;
      }
      set { _community = value; }
    }

    #endregion

    ///<summary>
    ///  Community file changed
    ///</summary>
    public event EventHandler<DataChangedEvent> CommunityFileChanged;

    private void SetupFileWatcher()
    {
      //TODO: does this watcher stay in scope or get destroyed??

      if (!File.Exists(Settings.SourceXmlCommunityFilePath)) return;

      _fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(Settings.SourceXmlCommunityFilePath),
                                                 Path.GetFileName(Settings.SourceXmlCommunityFilePath))
                             {
                               NotifyFilter = NotifyFilters.LastWrite,
                               EnableRaisingEvents = true
                             };
      _fileSystemWatcher.Changed += ((sender, e) =>
                                       {
                                         _community = null;

                                         if (CommunityFileChanged != null)
                                         {
                                           CommunityFileChanged.Invoke(sender, new DataChangedEvent(e));
                                         }
                                       });
    }
  }
}